#include <stdio.h>
#include <time.h>

#include "sqlite3.h"
#include "log.h"

int try_create_workdetail_table(sqlite3 *db)
{
	return SQLITE_OK;
}

static inline int get_today_str(char *today_str)
{
	time_t rawtime;
    struct tm *timeinfo;

    time(&rawtime);
    timeinfo = localtime(&rawtime);

    int year = timeinfo->tm_year + 1900;
    int month = timeinfo->tm_mon + 1;
	int day = timeinfo->tm_mday;
	sprintf(today_str, "%04d-%02d-%02d",year,month,day);
	return 0;
}

static inline void ms_to_hms(unsigned long ms, int *hours, int *minutes, int *seconds, int *milliseconds,char *hms)
{
	int h = 0, m = 0, s = 0, _ms = 0;
	// 计算小时
	h = ms / (1000 * 60 * 60);  // 1小时 = 1000ms * 60s * 60m
	ms %= (1000 * 60 * 60);          // 取余，得到剩余的毫秒	
	// 计算分钟
	m = ms / (1000 * 60);     // 1分钟 = 1000ms * 60s
	ms %= (1000 * 60);               // 取余，得到剩余的毫秒
	// 计算秒
	s = ms / 1000;            // 1秒 = 1000ms
	_ms = ms % 1000;       // 取余，得到剩余的毫秒

	if (hours != NULL)
		*hours = h;
	if (minutes != NULL)
		*minutes = m;
	
	if (seconds != NULL)
		*seconds = s;
	if (milliseconds != NULL)
		*milliseconds = _ms;
	if (hms != NULL)
		sprintf(hms, "%02d:%02d:%02d.%d",h,m,s,_ms);
	
}


int main(int argc, char *argv[])
{
	sqlite3_int64 today_acctime = 0;
	sqlite3_int64 today_worktime = 0;
	sqlite3_int64 today_waittime = 0;
	char today[12] = { 0 };
	char *errmsg = NULL;
	sqlite3 *db;
	get_today_str(today);

	int rc = sqlite3_open("d0.db", &db);
	if (rc != SQLITE_OK)
	{
		log_error("sqlite3_open fail rc:%d",rc);
		return 1;
	}
	
	rc = sqlite3_exec(db,
		"CREATE TABLE IF NOT EXISTS work("
		"id INTEGER PRIMARY KEY AUTOINCREMENT,"
		"date Text NOT NULL,"
		"push INTEGER DEFAULT 0,"
		"status INTEGER DEFAULT 1,"
		"acctime INTEGER DEFAULT 0,"
		"worktime INTEGER DEFAULT 0,"
		"waittime INTEGER DEFAULT 0"
		");",
		NULL, NULL, NULL);
	if (rc != SQLITE_OK)
	{
		log_error("sqlite3_exec create table (work) fail rc:%d errmsg:%s",rc,sqlite3_errmsg(db));
		sqlite3_close(db);
		return 1;
	}
	int tr_suf = 1;
	// 开启事务
	const char *bg_tr = "BEGIN TRANSACTION;";
	rc = sqlite3_exec(db, bg_tr, NULL, NULL, NULL);
	if (rc != SQLITE_OK)
	{
		log_error("fail:%s plz retry sql:%s", sqlite3_errmsg(db),bg_tr);
	}
	// 查询未推送的工作时间
	const char *sql0 = "SELECT id,date,acctime,worktime,waittime FROM work WHERE status = 1 AND push = 0 AND date != ?";
	sqlite3_stmt *stmt0;
	rc = sqlite3_prepare_v2(db, sql0, -1, &stmt0, 0);
	if (rc != SQLITE_OK)
	{
		log_error("sqlite3_prepare_v2 %s fail :%s", sql0, sqlite3_errmsg(db));
		sqlite3_close(db);
		return 1;
	}
	sqlite3_bind_text(stmt0, 1, today,-1,SQLITE_STATIC);
	int count = 0;
	while ((rc = sqlite3_step(stmt0)) == SQLITE_ROW)
	{
		sqlite3_int64 id = sqlite3_column_int64(stmt0, 0);
		const char *date = sqlite3_column_text(stmt0, 1);
		sqlite3_int64 acctime = sqlite3_column_int64(stmt0, 2);
		sqlite3_int64 worktime = sqlite3_column_int64(stmt0, 3);
		sqlite3_int64 waittime = sqlite3_column_int64(stmt0, 4);
		char acctime_str[32] = { 0 };
		char worktime_str[32] = { 0 };
		char waittime_str[32] = { 0 };
		ms_to_hms(acctime, NULL, NULL, NULL, NULL, acctime_str);
		ms_to_hms(worktime, NULL, NULL, NULL, NULL, worktime_str);
		ms_to_hms(waittime, NULL, NULL, NULL, NULL,waittime_str);
		log_debug("id:%d date:%s acctime:%s worktime:%s waittime:%s to push!!", id, date, acctime_str,worktime_str,waittime_str);
		count++;
		// TODO 推送
		char update_sql[256] = { 0 };
		snprintf(update_sql, sizeof(update_sql), "UPDATE work SET push = 1 WHERE id = %lld;", id);
		rc = sqlite3_exec(db, update_sql, NULL,NULL,NULL);
		if (rc != SQLITE_OK)
		{
			log_error("rc:%d fail: %s sql:%s\n", rc, sqlite3_errmsg(db), update_sql);
		}
		else
		{
			log_info("id:%lld update finish rc:%d sql:%s", id, rc, update_sql);
		}
	}
	// 重设 方便后续使用
	sqlite3_reset(stmt0);
	if (count == 0)
	{
		log_info("not find rc:%d push=0 date != %s", rc, today);
	}
	char *tr = tr_suf ? "COMMIT;" : "ROLLBACK;";
	// 提交事务 / 会滚
	rc = sqlite3_exec(db, tr, NULL, NULL, NULL);
	if (rc != SQLITE_OK)
	{
		log_error("rc:%d fail:%s sql:%s",rc, sqlite3_errmsg(db),tr);
	}
	

	sqlite3_stmt *stmt1;
	const char *sql1 = "SELECT id,acctime,worktime,waittime FROM work WHERE status = 1 AND push = 0 AND date = ?";
	rc = sqlite3_prepare_v2(db, sql1, -1, &stmt1, 0);
	if (rc != SQLITE_OK)
	{
		log_error("sqlite3_prepare_v2 %s fail :%s", sql1, sqlite3_errmsg(db));
	}
	else
	{
		count = 0;
		sqlite3_bind_text(stmt1, 1, today, -1, SQLITE_STATIC);
		while ((rc = sqlite3_step(stmt1)) == SQLITE_ROW)
		{
			sqlite3_int64 id = sqlite3_column_int64(stmt1, 0);
			sqlite3_int64 acctime = sqlite3_column_int64(stmt1, 1);
			sqlite3_int64 worktime = sqlite3_column_int64(stmt1, 2);
			sqlite3_int64 waittime = sqlite3_column_int64(stmt1, 3);
			char acctime_str[32] = { 0 };
			char worktime_str[32] = { 0 };
			char waittime_str[32] = { 0 };
			ms_to_hms(acctime, NULL, NULL, NULL, NULL, acctime_str);
			ms_to_hms(worktime, NULL, NULL, NULL, NULL, worktime_str);
			ms_to_hms(waittime, NULL, NULL, NULL, NULL,waittime_str);
			log_debug("today[%s]: id:%d acctime:%s worktime:%s waittime:%s", today,id, acctime_str, worktime_str, waittime_str);
			today_acctime += acctime;
			today_worktime += worktime;
			today_waittime += waittime;
			count++;
		}

		if (rc == SQLITE_DONE)
		{
			log_debug("count:%d %s finish", count, sql1);// sql里面有'\0' 会阻断打印
		}
		sqlite3_finalize(stmt1);

		// 无本日数据则插入一条
		if (count == 0)
		{
			sqlite3_stmt *stmt2;
			const char *sql2 = "INSERT INTO work (date) VALUES (?)";
			rc = sqlite3_prepare_v2(db, sql2, -1, &stmt2, 0);
			if (rc != SQLITE_OK)
			{
				log_error("sqlite3_prepare_v2 %s fail :%s", sql2, sqlite3_errmsg(db));
			}
			else
			{
				sqlite3_bind_text(stmt2, 1, today,-1,SQLITE_STATIC);
				rc = sqlite3_step(stmt2);
				if (rc != SQLITE_DONE)
				{
					log_debug("insert work %s finish rc:%d fail:%s",today,rc,sqlite3_errmsg(db));
				}
				sqlite3_finalize(stmt2);
			}

		}
		else
		{
			
		}
	}
	
	sqlite3_finalize(stmt0);
	sqlite3_close(db);
	return 0;
}